home *** CD-ROM | disk | FTP | other *** search
/ Fritz: All Fritz / All Fritz.zip / All Fritz / FILES / PROGNG_C / M2DOC.LZH / XFERDEMO.MOD < prev   
Text File  |  1987-07-04  |  4KB  |  143 lines

  1. MODULE xferdemo;
  2.  
  3. (* (C) Copyright 1987 Fitted Software Tools. All rights reserved. *)
  4.  
  5. (*
  6.     This is a small example showing the use of the coroutine handling
  7.     capabilities in this Modula-2 system.
  8. *)
  9.  
  10. FROM SYSTEM     IMPORT ASSEMBLER, ADDRESS, NEWPROCESS, TRANSFER, IOTRANSFER;
  11. FROM Storage    IMPORT ALLOCATE;
  12. FROM System     IMPORT GetVector, ResetVector, TermProcedure;
  13. FROM InOut      IMPORT Write, WriteCard, WriteLn;
  14.  
  15. VAR SysPrtScr   :ADDRESS;           (* original PrtSc ISR *)
  16.     SysClock    :ADDRESS;           (* original clock ISR *)
  17.     ProcSpace   :POINTER TO CHAR;   (* pointers to processes workspaces *)
  18.     ClockSpace  :POINTER TO CHAR;
  19.     StopSpace   :POINTER TO CHAR;
  20.     p1, p2      :ADDRESS;           (* coroutine (process) pointers *)
  21.     p3, p4      :ADDRESS;
  22.     p5, p6      :ADDRESS;
  23.     ticks       :CARDINAL;          (* tick counter *)
  24.     xfers       :CARDINAL;          (* transfers performed during run *)
  25.     done        :BOOLEAN;           (* terminate flag *)
  26.  
  27.  
  28. PROCEDURE clock;
  29. (*
  30.     this is the clock process.
  31.  
  32.     it increments 'ticks' on every clock interrupt.
  33.  
  34.     from the time that this process starts until such time as
  35.     the program terminates, the system timer will not be updated,
  36.     as this routine ruthlessly steals the clock interrupts from DOS.
  37.  
  38.     it would have been much better to run this process off interrupt
  39.     1CH, but in that case we would not have to send the EOI to the
  40.     8259 chip, making this exercise a little less instructive.
  41. *)
  42. BEGIN
  43.     LOOP
  44.         IOTRANSFER( p3, p4, 8 );
  45.         INC(ticks);
  46.         ASM (* send EOI to 8259 *)
  47.             MOV     AL, 20H         (* the 8259 interrupt controller will *)
  48.             OUT     20H, AL         (* prevent all interrupt at or below  *)
  49.                                     (* our level until we send it an EOI  *)
  50.         END;                        (* command                            *)
  51.     END;
  52. END clock;
  53.  
  54.  
  55. PROCEDURE putT;
  56. (*
  57.     this is a process that works hand in hand with the main process.
  58.  
  59.     it alternately outputs a 'T' or a 't' and resumes the main process.
  60. *)
  61. BEGIN
  62.     LOOP
  63.         Write('T');
  64.         TRANSFER( p2, p1 );
  65.         Write('t');
  66.         TRANSFER( p2, p1 );
  67.     END;
  68. END putT;
  69.  
  70.  
  71. PROCEDURE stop;
  72. (*
  73.     this process will signal the main process that the user wishes
  74.     to terminate the program by setting 'done' to TRUE whenever
  75.     the user presses the PrtSC key generating a 'print screen'
  76.     interrupt.
  77.  
  78.     we do not simply terminate the program with a RETURN, because we
  79.     may be in DOS when the interrupt occurs.
  80. *)
  81. BEGIN
  82.     LOOP
  83.         IOTRANSFER( p5, p6, 5 );
  84.         done := TRUE;
  85.     END;
  86. END stop;
  87.  
  88.  
  89. PROCEDURE end;
  90. (*
  91.     this is the procedure to be executed on program termination.
  92.  
  93.     we MUST restore the interrupt vectors that we have stolen.
  94. *)
  95. BEGIN
  96.     ResetVector( 5, SysPrtScr );
  97.     ResetVector( 8, SysClock );
  98. END end;
  99.  
  100.  
  101. BEGIN
  102.     done := FALSE;
  103.     ticks := 0;
  104.     xfers := 0;
  105.  
  106.     GetVector( 5, SysPrtScr );      (* get the original values of the *)
  107.     GetVector( 8, SysClock );       (* interrupt vectors that we will use *)
  108.     TermProcedure( end );           (* and install 'end' to execute on *)
  109.                                     (* program termination *)
  110.  
  111.     (* now, create the new processes *)
  112.  
  113.     ALLOCATE( ProcSpace, 512 );
  114.     NEWPROCESS( putT, ProcSpace, 512, p2 );
  115.  
  116.     ALLOCATE( ClockSpace, 512 );
  117.     NEWPROCESS( clock, ClockSpace, 512, p3 );
  118.  
  119.     ALLOCATE( StopSpace, 512 );
  120.     NEWPROCESS( stop, StopSpace, 512, p5 );
  121.  
  122.     (* start the 'stop' process *)
  123.     TRANSFER( p6, p5 );
  124.  
  125.     (* start the 'clock' process *)
  126.     TRANSFER( p4, p3 );
  127.  
  128.     (*
  129.         this is the main loop of the main process.
  130.  
  131.         on every loop, the 'done' flag is checked and, if it is not time
  132.         to stop, we write out the value of ticks and reactivate the 'putT'
  133.         process.
  134.     *)
  135.     WHILE NOT done DO
  136.         WriteCard( ticks, 6 );
  137.         TRANSFER( p1, p2 );
  138.         INC( xfers );
  139.     END;
  140.  
  141.     WriteLn; WriteCard( xfers, 4 ); WriteLn;
  142.  
  143. END xferdemo.